A thread of execution, kernel thread, or simply “thread,” is a sequence of programmed instructions, or functions, managed independently by an operating system scheduler. In most cases, a thread is contained inside a process. Multiple threads can exist within the same process and share resources including: (i) instruction code; (ii) variable values at any given moment (context); (iii) process state; (iv) memory; and (v) address space.
Each thread has a reserved region of memory referred to as its stack. The stack is made of current stackframes. See Definitions section of the Detailed Description for the definitions of “stack” and “current stackframes.” Each stackframe relates to a function executed by the tread and usually contains a header (with a pointer to the previous stackframe), the variables allocated by the function and also a copy of the register values (like the program counter) from the time when the function was called. Initially the stack does not contain current stackframes and its content is old data, or non-current stack portions (also sometimes called “garbage”). See Definitions sub-section of the Detail Description section for the definition of current stackframes. However, as the thread executes, its stack begins to fill with current stackframes. The number of current stackframes in the stack grows and decreases during the execution depending on the number of functions in the call graph (also called call-chain).
When a function is called, the calling function may create a new stackframe and store some registers there defined by the application binary interface (ABI). The called function may grow the stackframe that the caller created to include some temporary variables (with a lifescope equal to or less than the execution time of the function) of the function and preserve additional registers as defined by the ABI. When the function exits, the function restores the original register values from the stack, including the program counter that contains an address within the caller function. On return, the caller function deletes the stackframe, but usually, for the sake of performance, the memory is not clean and just the end of stack pointer is updated. If a region of memory lies on the thread's stack, that memory is said to have been allocated on the stack.
Memory dumps are useful in debugging software problems. Typical dump size is growing quickly, because, among other reasons, the number of threads used in a typical program is growing, making it difficult to store and/or transmit the data of the memory dump (the data of a memory dump is also commonly referred to as a “memory dump” or “dump”). It is known to split memory dumps into regions and truncate the dumps to be limited to only the important regions. It is also known to apply data compression techniques to the memory dump, thus reducing the dump size. A memory dump may include: (i) all of the stacks; (ii) none of the stacks; and/or (iii) selected whole stacks (such as the whole stack of the crashing thread).